#include "Scene.h"

#include <Inventor/SbName.h>
#include <Inventor/SoPath.h>
#include <Inventor/SoInput.h>
#include <Inventor/Win/SoWin.h>
#include <Inventor/Win/SoWinRenderArea.h>
#include <Inventor/nodes/SoSelection.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoRotationXYZ.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoText3.h>
#include <Inventor/nodes/SoArray.h>

static SbBool renderAreaEventCB(void *, MSG *anyEvent)
{
	SbBool bHandled = FALSE;

	switch(anyEvent->message)
	{
	case WM_KEYDOWN:
		{
			switch(anyEvent->wParam)
			{
			case VK_UP:
				{
					Scene::getInstance()->rotateXaxis(-0.1570796f);
					bHandled = TRUE;
					break;
				}
			case VK_DOWN:
				{
					Scene::getInstance()->rotateXaxis(+0.1570796f);
					bHandled = TRUE;
					break;
				}
			case VK_RIGHT:
				{
					Scene::getInstance()->rotateYaxis(-0.1570796f);
					bHandled = TRUE;
					break;
				}
			case VK_LEFT:
				{
					Scene::getInstance()->rotateYaxis(+0.1570796f);
					bHandled = TRUE;
					break;
				}
			case VK_RETURN:
				{
					//if(NULL != Scene::getInstance()->getSelectedPiece())
					//{
					//	//GameSession::getInstance()->confirmSelection();
					//}
					bHandled = TRUE;
					break;
				}
			default:
				{
					break;
				}
			}
			break;
		}
	default:
		{
			break;
		}
	}
	return bHandled;
}

Scene * Scene::s_pInstance = NULL;

Scene * Scene::getInstance(void)
{
	return s_pInstance;
}

Scene * Scene::createInstance(HWND hWnd)
{
	if(NULL != s_pInstance)
	{
		deleteInstance();
	}
	s_pInstance = new Scene(hWnd);
	return s_pInstance;
}

void Scene::deleteInstance(void)
{
	if(NULL != s_pInstance)
	{
		delete s_pInstance;
		s_pInstance = NULL;
	}
}

Scene::Scene(HWND hWnd)
{
	m_hWnd = hWnd;
	init();
}

Scene::~Scene(void)
{
	SoWin::done();
	m_pSelectionRoot->unref();
	m_pBoard->unref();
	m_pAllPieces->unref();
}

//Scene * Scene::createInstance(HWND hWnd)
void Scene::init(void)
{
	SoWin::init(m_hWnd);
	m_pRenderArea = new SoWinRenderArea(m_hWnd);
	m_pRoot = new SoSeparator();
	m_pRoot->ref();

	SoPerspectiveCamera * pCamera = new SoPerspectiveCamera();
	pCamera->viewAll(m_pRoot, m_pRenderArea->getViewportRegion());
	m_pRoot->addChild(pCamera);
	SoDirectionalLight * pLight = new SoDirectionalLight();
	m_pRoot->addChild(pLight);

	SoInput inputBoard;
	if(!inputBoard.openFile("BoardTest.wrl"))
	{
		MessageBox(NULL, TEXT("Could not open file 'BoardTest.wrl'"), TEXT("Scene"), MB_OK);
	}
	m_pBoard = SoDB::readAll(&inputBoard);
	m_pBoard->ref();
	inputBoard.closeFile();
	m_pRoot->addChild(m_pBoard);

	//other input

	pCamera->viewAll(m_pRoot, m_pRenderArea->getViewportRegion());
	m_pRenderArea->setSceneGraph(m_pSelectionRoot);
	m_pRenderArea->setTitle("Hi");
	m_pRenderArea->setEventCallback(renderAreaEventCB);
	m_pRenderArea->show();

	SoWin::show(m_hWnd);

	//SoWin::init(m_hWnd);
	////SoWinRenderArea * renderarea = new SoWinRenderArea(hWnd);
	//m_pRenderArea = new SoWinRenderArea(m_hWnd);

	////m_fAngleRotationXaxis = 0.9424776f;
	////m_fAngleRotationYaxis = 0.0f;

	////m_pSelectionRoot = new SoSelection();
	////m_pSelectionRoot->ref();

	//m_pRoot = new SoSeparator();
	//m_pRoot->ref();
	////m_pSelectionRoot->addChild(m_pRoot);

	//SoPerspectiveCamera * pCamera = new SoPerspectiveCamera();
	//pCamera->viewAll(m_pRoot, m_pRenderArea->getViewportRegion());
	//m_pRoot->addChild(pCamera);
	//SoDirectionalLight * pLight = new SoDirectionalLight();
	//m_pRoot->addChild(pLight);

	////SoRotationXYZ * pRotX = new SoRotationXYZ();
	////pRotX->setName(SbName("X_Rotation"));
	////pRotX->axis = SoRotationXYZ::X;
	////pRotX->angle.setValue(m_fAngleRotationXaxis);
	////m_pRoot->addChild(pRotX);
	////SoRotationXYZ * pRotY = new SoRotationXYZ();
	////pRotY->setName(SbName("Y_Rotation"));
	////pRotY->axis = SoRotationXYZ::Y;
	////pRotY->angle.setValue(m_fAngleRotationYaxis);
	////m_pRoot->addChild(pRotY);

	//SoInput inputBoard;
	//if(!inputBoard.openFile("BoardTest.wrl"))
	//{
	//	MessageBox(NULL, TEXT("Could not open file 'BoardTest.wrl'"), TEXT("Scene"), MB_OK);
	//}
	//m_pBoard = SoDB::readAll(&inputBoard);
	//m_pBoard->ref();
	//inputBoard.closeFile();
	//m_pRoot->addChild(m_pBoard);

	////SoInput inputPieces;
	////if(!inputPieces.openFile("playerTest1.wrl"))
	////{
	////	MessageBox(NULL, TEXT("Could not open file 'playerTest1.wrl'"), TEXT("Scene"), MB_OK);
	////}
	////m_pAllPieces = SoDB::readAll(&inputPieces);
	////m_pAllPieces->ref();
	////inputPieces.closeFile();

	////m_pPiecesRoot = new SoSeparator();
	////m_pRoot->addChild(m_pPiecesRoot);

	//pCamera->viewAll(m_pBoard, m_pRenderArea->getViewportRegion());

	////m_pRenderArea->setSceneGraph(m_pSelectionRoot);
	////m_pRenderArea->setTitle("POO");
	//m_pRenderArea->setEventCallback(renderAreaEventCB);
	//m_pRenderArea->show();

	//SoWin::show(m_hWnd);
}

void Scene::refresh(void)
{
	m_pRenderArea->render();
}

//SoSelection & Scene::getRoot(void)
//{
//	return *m_pSelectionRoot;
//}

//void Scene::removeAllPieces(void)
//{
//	m_pPiecesRoot->removeAllChildren();
//	m_pRenderArea->render();
//}

void Scene::rotateXaxis(float fAngle)
{
	m_fAngleRotationXaxis += fAngle;
	if(m_fAngleRotationXaxis < 0.0f)
	{
		m_fAngleRotationXaxis = 0.0f;
	}
	if(m_fAngleRotationXaxis > 1.570796f)
	{
		m_fAngleRotationXaxis = 1.570796f;
	}
	SoRotationXYZ *xRotation = (SoRotationXYZ *) SoNode::getByName(SbName("X_Rotation"));
	xRotation->angle.setValue(m_fAngleRotationXaxis);
}

void Scene::rotateYaxis(float fAngle)
{
	m_fAngleRotationYaxis += fAngle;
	if(m_fAngleRotationYaxis < -3.141592f)
	{
		m_fAngleRotationYaxis = -3.141592f;
	}
	if(m_fAngleRotationYaxis > +3.141592f)
	{
		m_fAngleRotationYaxis = +3.141592f;
	}
	SoRotationXYZ *yRotation = (SoRotationXYZ *) SoNode::getByName(SbName("Y_Rotation"));
	yRotation->angle.setValue(m_fAngleRotationYaxis);
}